package main

import (
	"fmt"
	cmap "github.com/orcaman/concurrent-map/v2"
	"sync"
)

// orcaman/concurrent-map 是一个非常流行的 Go 语言第三方并发安全 Map 库，它的核心设计思想是 “分片加锁”
// 本质：一个基于 Go 内置 map 实现的并发安全数据结构。
// 核心原理：将一个大的 map 分成多个小的 map（称为 “分片”），每个分片都由一把独立的读写锁（sync.RWMutex）保护。
// go get github.com/orcaman/concurrent-map/v2
func main() {
	//_demo6()
	_demo7()
}

// 1. 测试普通 map（预期会崩溃）
func _demo6() {
	fmt.Println("=== 测试普通 map（并发读写）===")
	regularMap := make(map[string]int)
	var wg sync.WaitGroup

	// 启动 100 个 Goroutine 并发读写
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(n int) {
			defer wg.Done()
			key := fmt.Sprintf("key_%d", n%10) // 故意让多个 Goroutine 操作同一个 key

			// 写操作
			regularMap[key] = n

			// 读操作
			fmt.Printf("普通 map: key=%s, value=%d\n", key, regularMap[key])
		}(i)
	}

	wg.Wait()

	// fatal error: concurrent map writes
	fmt.Println("普通 map 测试完成（会崩溃）=== 此行不会输出!")
}

// 2. 测试 concurrent-map（预期安全）
func _demo7() {
	fmt.Println("=== 测试 concurrent-map（并发读写）===")
	concurrentMap := cmap.New[int]()
	var wg sync.WaitGroup

	// 启动 100 个 Goroutine 并发读写
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func(n int) {
			defer wg.Done()
			key := fmt.Sprintf("key_%d", n%10) // 同样让多个 Goroutine 操作同一个 key

			// 写操作
			concurrentMap.Set(key, n)

			// 读操作
			value, exists := concurrentMap.Get(key)
			if exists {
				fmt.Printf("concurrent-map: key=%s, value=%d\n", key, value)
			}
		}(i)
	}

	wg.Wait()
	fmt.Println("concurrent-map 测试完成（安全无崩溃）")
}
